package org.sample.commons.net;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.List;

public enum HttpClient {

    Instance;

    public static HttpClient getInstance() {
        return Instance;
    }

    private CloseableHttpClient httpClient;

    private PoolingHttpClientConnectionManager cm;

    HttpClient() {
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(2000)//建立连接超时时间
                .setSocketTimeout(2000)//响应超时时间
                .setConnectionRequestTimeout(4500)//从连接池中获取连接超时时间
                .setRedirectsEnabled(false)
                .setExpectContinueEnabled(true)
                .build();

        cm = new PoolingHttpClientConnectionManager();
        //最大连接数量
        cm.setMaxTotal(50);
        //单个路由最大连接数量
        cm.setDefaultMaxPerRoute(10);

        httpClient = HttpClients.custom()
                .setConnectionManager(cm)
                .setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE)
                .setRetryHandler(DefaultHttpRequestRetryHandler.INSTANCE)
                .setDefaultRequestConfig(requestConfig)
                .build();
    }

    public String doGet(String url) {
        HttpGet request = new HttpGet(url);
        return executeInternal(request);
    }

    public String doGet(String url, String... param) {
        url = NetUtils.buildUrl(url, param);
        HttpGet request = new HttpGet(url);
        return executeInternal(request);
    }

    public String doPost(String url, String requestBody) {
        HttpPost request = new HttpPost(url);
        StringEntity requestEntity = new StringEntity(requestBody, ContentType.APPLICATION_JSON);
        request.setEntity(requestEntity);

        return executeInternal(request);
    }

    public String doPost(String url, List<BasicNameValuePair> requestBody) {
        HttpPost request = new HttpPost(url);
        request.setEntity(new UrlEncodedFormEntity(requestBody, Consts.UTF_8));

        return executeInternal(request);
    }

    public String executeInternal(HttpUriRequest request) {
        try (CloseableHttpResponse response = httpClient.execute(request)) {
            HttpEntity entity = response.getEntity();
            return entity != null ? EntityUtils.toString(entity, Consts.UTF_8) : null;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}